﻿Imports System.Drawing
Imports System.IO
Imports System.Drawing.Imaging
Imports System.Threading
Imports System.Runtime.InteropServices

Public Class MainForm
    Private filetypes As String
    Private listtypes() As String = {".bmp", ".jpg", ".ico", ".jpeg", ".png", ".tif"}
    Private folderpos As Integer
    Private added_img As Image
    Public pathlist As New ArrayList
    Public filename As String = "Unnamed"

#Region "MainForm Methods"

    Private Sub MainForm_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        Dim language As String
        filetypes = "Windows Bitmap (*.bmp)|*.bmp" & "|JPEG Files (*.jpg; *.jpeg)|*.jpg" &
            "|Portable Network Graphics (*.png)|*.png" & "|TIFF Files (*.tif)|*.tif" & "|Windows Icons (*.ico)|*.ico" &
            "|All Files (*.*)|*.*"
        statAbout.Text = "v." & Me.ProductVersion & statAbout.Text
        language = Thread.CurrentThread.CurrentUICulture.TwoLetterISOLanguageName
        If language = "de" Then
            conLanguageEng.Checked = False
            conLanguageDe.Checked = True
        Else
            conLanguageEng.Checked = True
            conLanguageDe.Checked = False
        End If
        MyBase.KeyPreview = True
    End Sub

    Private Sub MainForm_Shown(sender As Object, e As EventArgs) Handles MyBase.Shown
        If My.Application.CommandLineArgs.Count > 0 Then
            Dim starting_arg As String = My.Application.CommandLineArgs(0)
            If File.Exists(starting_arg) Then
                image_Set(0, starting_arg)
                If lblError.Visible = False Then images_Load(starting_arg)
            End If
        End If
    End Sub

    Private Sub MainForm_Resize(sender As Object, e As EventArgs) Handles MyBase.Resize
        If filename <> "Unnamed" Then Adjust_Image()
    End Sub


    Private Sub key_Down(sender As Object, e As KeyEventArgs) Handles Me.KeyDown
        If e.KeyCode = Keys.Left AndAlso butBackward.Enabled = True Then
            butBackward_Click(sender, e)
        ElseIf e.KeyCode = Keys.Right AndAlso butForward.Enabled = True Then
            butForward_Click(sender, e)
        ElseIf e.KeyCode = Keys.F1 Then
            conAbout_Click(sender, e)
        End If
    End Sub

#End Region

#Region "Set Image"

    Private Sub images_Load(image_path As String)
        pathlist.Clear()
        Dim img_info As New FileInfo(image_path)
        Dim i As Integer = 0
        Dim img_folder As String = img_info.DirectoryName
        For Each path In Directory.GetFiles(img_folder)
            If Array.IndexOf(listtypes, IO.Path.GetExtension(path).ToLower) <> -1 Then
                pathlist.Add(path)
                If path = image_path Then folderpos = i
                i += 1
            End If
        Next
        check_folderpos()
    End Sub

    Private Sub image_Set(index As Integer, Optional added_path As String = Nothing)
        If added_path Is Nothing Then added_path = pathlist(index)
        Dim img_info As New FileInfo(added_path)
        If Array.IndexOf(listtypes, img_info.Extension.ToLower) = -1 Then
            conClose_Click(Nothing, Nothing)
            statInfo.Text = My.Resources.LoadingError
            lblError.Visible = True
            Exit Sub
        Else
            lblError.Visible = False
        End If
        Try
            If img_info.Extension.ToLower = ".ico" Then
                Dim gico As New Icon(added_path)
                added_img = gico.ToBitmap
                gico.Dispose()
            Else
                Dim fs As New FileStream(added_path, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)
                added_img = Drawing.Image.FromStream(fs)
                fs.Close()
                fs.Dispose()
            End If
        Catch
            pathlist.Remove(added_path)
            conClose_Click(Nothing, Nothing)
            statInfo.Text = My.Resources.LoadingError
            lblError.Visible = True
            Exit Sub
        End Try
        picMain.MaximumSize = added_img.Size
        picMain.Image = added_img
        filename = img_info.Name
        Adjust_Image()
        picMain.Visible = True
        statInfo.Text = added_img.Width & " x " & added_img.Height & " px"
        statSize.Text = ConvertByteSize(img_info.Length)
        butDelete.Enabled = True
        butLeft.Enabled = True
        butRight.Enabled = True
        butSave.Enabled = True
        picMain.Focus()
    End Sub

    Private Sub Adjust_Image()
        Try
            Dim x_zoom As Integer = Math.Floor(panImage.Width / picMain.MaximumSize.Width * 100)
            Dim y_zoom As Integer = Math.Floor(panImage.Height / picMain.MaximumSize.Height * 100)
            Dim totalzoom As Double = Math.Min(x_zoom, y_zoom) / 100
            picMain.Height = totalzoom * picMain.MaximumSize.Height
            picMain.Width = totalzoom * picMain.MaximumSize.Width
            picMain.Location = New Point(Int((panImage.Width - picMain.Width) / 2), Int((panImage.Height - picMain.Height) / 2))
            If totalzoom > 1 Then totalzoom = 1
            Me.Text = "miniViewer - " & filename & " (" & totalzoom * 100 & "%)"
        Catch
        End Try
    End Sub

#End Region

#Region "Navigate in Folder"

    Private Sub butBackward_Click(sender As Object, e As EventArgs) Handles butBackward.Click
        folderpos -= 1
        added_img.Dispose()
        image_Set(folderpos)
        check_folderpos()
        picMain.Focus()
    End Sub

    Private Sub butForward_Click(sender As Object, e As EventArgs) Handles butForward.Click
        folderpos += 1
        added_img.Dispose()
        image_Set(folderpos)
        check_folderpos()
        picMain.Focus()
    End Sub

    Private Sub check_folderpos()
        If folderpos > 0 Then
            butBackward.Enabled = True
        Else
            butBackward.Enabled = False
        End If
        If folderpos < pathlist.Count - 1 Then
            butForward.Enabled = True
        Else
            butForward.Enabled = False
        End If
    End Sub

#End Region

#Region "Filemenu"

    Private Sub butOpen_Click(sender As Object, e As EventArgs) Handles conOpen.Click, butOpen.Click
        ofdOpen.Filter = filetypes
        ofdOpen.FileName = ""
        If ofdOpen.ShowDialog() = Windows.Forms.DialogResult.OK Then
            If statSize.Text <> "" Then
                added_img.Dispose()
            End If
            picMain.Image = Nothing
            image_Set(0, ofdOpen.FileName)
            If lblError.Visible = False Then images_Load(ofdOpen.FileName)
        End If
        panImage.Focus()
    End Sub

    Private Sub butSave_Click(sender As Object, e As EventArgs) Handles conSaveAs.Click, butSave.Click
        Dim savetypes As String = filetypes.Substring(0, filetypes.Length - 48)
        sfdSave.Filter = savetypes
        sfdSave.FileName = filename
        sfdSave.ShowDialog()
        picMain.Focus()
    End Sub

    Private Sub save_Image() Handles sfdSave.FileOk
        Dim format As ImageFormat
        Select Case Path.GetExtension(sfdSave.FileName)
            Case ".bmp"
                format = ImageFormat.Bmp
            Case ".gif"
                format = ImageFormat.Gif
            Case ".jpg"
                format = ImageFormat.Jpeg
            Case ".png"
                format = ImageFormat.Png
            Case ".tif"
                format = ImageFormat.Tiff
            Case Else
                Exit Sub
        End Select
        added_img.Save(sfdSave.FileName, format)
    End Sub

    Private Sub conExit_Click(sender As Object, e As EventArgs) Handles conExit.Click
        Me.Close()
    End Sub

    Private Sub conPrint_Click(sender As Object, e As EventArgs) Handles conPrint.Click
        Dim pwz As New Process
        pwz.StartInfo.Verb = "print"
        pwz.StartInfo.FileName = pathlist(folderpos)
        pwz.Start()
    End Sub

    Private Sub conClose_Click(sender As Object, e As EventArgs) Handles conClose.Click
        If statSize.Text <> "" Then added_img.Dispose()
        picMain.Image = Nothing
        statInfo.Text = ""
        statSize.Text = ""
        Me.Text = "miniViewer"
        filename = "Unnamed"
        pathlist.Clear()
        folderpos = 0
        butDelete.Enabled = False
        butLeft.Enabled = False
        butRight.Enabled = False
        butSave.Enabled = False
        lblError.Visible = False
        check_folderpos()
    End Sub

    Private Sub contxtFile_Opening(sender As Object, e As System.ComponentModel.CancelEventArgs) Handles contxtFile.Opening
        If statSize.Text <> "" Then
            conSaveAs.Enabled = True
            conPrint.Enabled = True
        Else
            conSaveAs.Enabled = False
            conPrint.Enabled = False
        End If
        If statSize.Text <> "" Or lblError.Visible = True Then
            conClose.Enabled = True
        Else
            conClose.Enabled = False
        End If
    End Sub

#End Region

#Region "Editmenu"

    Private Sub contxtEdit_Opening(sender As Object, e As System.ComponentModel.CancelEventArgs) Handles contxtEdit.Opening
        If statSize.Text <> "" Then
            conCopy.Enabled = True
            conRotLeft.Enabled = True
            conRotRight.Enabled = True
            conFlip.Enabled = True
            conDelete.Enabled = True
        Else
            conCopy.Enabled = False
            conRotLeft.Enabled = False
            conRotRight.Enabled = False
            conFlip.Enabled = False
            conDelete.Enabled = False
        End If
    End Sub

    Private Sub butLeft_Click(sender As Object, e As EventArgs) Handles conRotLeft.Click, butLeft.Click
        added_img.RotateFlip(RotateFlipType.Rotate270FlipNone)
        picMain.Image = added_img
        picMain.MaximumSize = added_img.Size
        Adjust_Image()
        picMain.Focus()
    End Sub

    Private Sub butRight_Click(sender As Object, e As EventArgs) Handles conRotRight.Click, butRight.Click
        added_img.RotateFlip(RotateFlipType.Rotate90FlipNone)
        picMain.Image = added_img
        picMain.MaximumSize = added_img.Size
        Adjust_Image()
        picMain.Focus()
    End Sub

    Private Sub conCopy_Click(sender As Object, e As EventArgs) Handles conCopy.Click
        Clipboard.SetImage(added_img)
    End Sub

    Private Sub conFlip_Click(sender As Object, e As EventArgs) Handles conFlip.Click
        added_img.RotateFlip(RotateFlipType.RotateNoneFlipX)
        picMain.Image = added_img
        picMain.MaximumSize = added_img.Size
        Adjust_Image()
        picMain.Focus()
    End Sub

    Private Sub conDelete_Click(sender As Object, e As EventArgs) Handles conDelete.Click, butDelete.Click
        Try
            My.Computer.FileSystem.DeleteFile(pathlist(folderpos), FileIO.UIOption.AllDialogs, FileIO.RecycleOption.SendToRecycleBin,
                                              FileIO.UICancelOption.ThrowException)
            folderpos += 1
            added_img.Dispose()
            image_Set(folderpos)
            check_folderpos()
            picMain.Focus()
        Catch ex As OperationCanceledException
            picMain.Focus()
            Exit Sub
        Catch ex2 As ArgumentOutOfRangeException
            conClose_Click(sender, e)
        End Try
    End Sub

#End Region

#Region "Set Language"

    Private Sub conLanguageEng_Click(sender As Object, e As EventArgs) Handles conLanguageEng.Click
        Dim new_culture As New Globalization.CultureInfo("en")
        change_Culture(new_culture, sender, e)
    End Sub

    Private Sub conLanguageDe_Click(sender As Object, e As EventArgs) Handles conLanguageDe.Click
        Dim new_culture As New Globalization.CultureInfo("de")
        change_Culture(new_culture, sender, e)
    End Sub

    Private Sub change_Culture(culture As Globalization.CultureInfo, sender As Object, e As EventArgs)
        Dim old_path As String
        Try
            old_path = pathlist(folderpos)
        Catch
            old_path = ""
        End Try
        Thread.CurrentThread.CurrentUICulture = culture
        Thread.CurrentThread.CurrentCulture = culture
        If statSize.Text <> "" Then
            added_img.Dispose()
        End If
        Me.Controls.Clear()
        Me.DataBindings.Clear()
        InitializeComponent()
        MainForm_Load(sender, e)
        If old_path <> "" Then
            image_Set(0, old_path)
            If lblError.Visible = False Then images_Load(old_path)
        End If
        panImage.Focus()
    End Sub

#End Region

#Region "Options"

    Private Sub conAbout_Click(sender As Object, e As EventArgs) Handles conAbout.Click
        Info_Window.ShowDialog()
    End Sub

    Function ConvertByteSize(size As Long) As String
        Dim symbol() As String = {"Bytes", "KiB", "MiB", "GiB", "TiB", "PiB"}
        Dim csize As Double = size
        Dim x As Integer = 0
        Do While csize >= 1024
            csize /= 1024
            x += 1
        Loop
        csize = Math.Round(csize, 2)
        Return csize & " " & symbol(x)
    End Function

    Private Sub conDetect_Click(sender As Object, e As EventArgs) Handles conDetect.Click
        Dim proc_path As String = Path.GetDirectoryName(My.Application.Info.DirectoryPath) & "\miniColors\miniColors.exe"
        If File.Exists(proc_path) Then
            Dim hff_process As New System.Diagnostics.Process
            hff_process.StartInfo.FileName = proc_path
            hff_process.StartInfo.Arguments = "/detect"
            hff_process.Start()
        Else
            MessageBox.Show(My.Resources.hffError, "miniViewer", MessageBoxButtons.OK, MessageBoxIcon.Error)
        End If
    End Sub

#End Region

End Class
